class Topology{
  constructor(){
    this.nodes=[];
    this.connections=[];
    this.selectedNode=null;
    this.next_node_id=1;  // 用于产生Nodeid
    this.column_pitch=140;
    this.level_pitch=240;
  }

  appNode(parentId=undefined,prevId=undefined,data=undefined){
    const id = this.idFactory();
    const node={
      id,
      parentId,
      prevId,
      nextNode:undefined,
      children:[],
      level:parentId?this.getNodeById(parentId).level+1:0,
      data:data,
      x:40,
      y:30,
    };
    // 添加到节点列表
    this.nodes.push(node);

    // 更新父节点关系
    if(parentId){
      const parent = this.getNodeById(parentId);
      parent.children.push(node);
      this.updateTotalChildrenCount(parent);
    }

    // 更新前后节点关系
    if(prevId){
      const prev = this.getNodeById(prevId)
      prev.nextNode=node;
      if(!node.parentId&&prev.parentId){
        const parent = this.getNodeById(prev.parentId);
        node.parentId=prev.parentId;
        node.level = node.parentId? this.getNodeById(node.parentId).level+1:0;
        const prev_index = parent.children.findIndex(child => child.id==prev.id);
        if(prev_index<parent.children.length-1){
          parent.children.splice(prev_index+1,0,node);
        }
        else{
          parent.children.push(node);
        }
        // parent.children.push(node);
        this.updateTotalChildrenCount(parent);
      }
    }
    this.updateConnections();
    this.updateStatus();
    return node;
  }

  /**
   * 更新子节点合计
   * 递归统计子节数量
   * @param {*} node 节点
   */
  updateTotalChildrenCount(node){
    let count=0;
    node.children.forEach((node)=>{
      count+=(node.totalChildrenCount||1);
    });
    node.totalChildrenCount=count;
    if(node.parentId){
      let parent = this.getNodeById(node.parentId);
      if(parent){
        this.updateTotalChildrenCount(parent);
      }
    }
  }

  // 删除节点
  removNode(id){
    const node = this.getNodeById(id);
    if(!node) return;

    // 递归删除所有子节点
    node.children.forEach(node=>this.removNode(node.id));

    // 更新前后关系
    if(node.prevId){
      const prevNode = this.getNodeById(node.prevId);
      prevNode.nextNode=node.nextNode;
    }
    if(node.nextNode){
      node.nextNode.prevId=node.prevId;
    }

    // 从父节点移除
    if(node.parentId){
      const parent = this.getNodeById(node.parentId);
      parent.children=parent.children.filter(child_node=>child_node.id!=id);
      this.updateTotalChildrenCount(node);
    }

    // 从列表节点中移除
    this.nodes=this.nodes.filter(node=>node.id!=id);

    // 清除选择状态
    if(this.selectedNode==id) this.selectedNode=null;

    this.updateConnections();
    this.updateStatus();
    return node;
  }
  /**
   * 清理所有节点
   */
  clearNode(){
    this.nodes.length=0;
    this.connections.length=0;
  }
  // 选择节点
  selectNode(id) {
    this.selectedNode = id;
    this.updateStatus();
  }

  moveNode(id,x,y){
    const node = this.getNodeById(id);
    if(!node)return;
    node.x=x
    node.y=y;
    this.updateConnections();
  }

  updateConnections(){
    this.connections.length=0;
    this.nodes.forEach(node => {
      if(node.parentId){
        const parent = this.getNodeById(node.parentId);
        if(node.prevId){
          this.connections.push({
            type:"parent_prev",
            from:parent,
            to:node
          });
        }else{
          this.connections.push({
            type:"parent",
            from:parent,
            to:node
          });
        }
      }
      if(node.nextNode){
        this.connections.push({
          type:"sibling",
          from:node,
          to:node.nextNode
        })
      }
    })
  }
  
  updateStatus(){}

  // 自动布局
  arrangeLayout(){
    // 按层级排列节点
    const levels ={};

    // 分组节点层级
    this.nodes.forEach(node => {
      if(!levels[node.level])levels[node.level] = [];
      levels[node.level].push(node);
    })

    // 计算每个节点的位置
    const rootNodes=levels[0];

    // 计算子节点位置
    const computChildrenPosition=function(node){
      for(let i=0;i<node.children.length;i++){
        const child = node.children[i];
        var offset_x = 0;
        if(i>0){
          const prevNode = node.children[i-1];
          offset_x = prevNode.totalChildrenCount>1?(prevNode.totalChildrenCount-1)*this.column_pitch:0;
          child.x=prevNode.x+offset_x+this.column_pitch;
        }else{
          child.x=node.x;
        }
        child.y=child.level*this.level_pitch;
        computChildrenPosition.call(this,child);
      }
    }

    // 计算根节点位置
    for(let i=0;i<rootNodes.length;i++){
      const node = rootNodes[i];
      var offset_x = 0;
      if(i>0){
        const prevNode = rootNodes[i-1];
        offset_x = prevNode.totalChildrenCount>1?(prevNode.totalChildrenCount-1)*this.column_pitch:0;
        node.x=prevNode.x + offset_x+this.column_pitch;
      }else{
        node.x = 0;
      }
      node.y=0;
      computChildrenPosition.call(this,node);
    }

    // 重新计算父级节点位置
    const recount=function(node){
      if(node.totalChildrenCount>0){
        // node.x=node.x+(node.totalChildrenCount*this.column_pitch)/2;
        node.x=(node.children[0].x+node.children[node.children.length-1].x)/2-1;  // -1 是为了防止中间节点的连线无法正确显示
        for(let i=0;i<node.children.length;i++){
          recount.call(this,node.children[i]);
        }
      }
    }
    rootNodes.forEach((node) => {
      recount.call(this,node);
    });

    // // 计算每个节点的位置
    // Object.keys(levels).forEach(level => {
    //   const nodes = levels[level];
    //   let i=0;
    //   nodes.forEach((node,index) => {
    //     console.log("arrangeLayout", level, node.level,index);
    //     const parentNode = this.getNodeById(node.parentId);
    //     node.x=index*this.column_pitch+(parentNode?parentNode.x:0)-1;
    //     // node.x=index*this.column_pitch-1+i%3;
    //     node.y=parseInt(level)*this.level_pitch+i%2;  // +i%2  是为了防止节点中的连线无法正确显示
    //     i++;
    //   })
    // });

    // // 重新计算父级节点位置
    // const rootNodes = this.nodes.filter(node => !node.parentId);
    // const recount=function(node){
    //   if(!node.children||node.children.length==0||node.nextNode)return;
    //   node.children.forEach(child_node=>{
    //     recount(child_node);
    //   })
    //   node.x=(node.children[0].x+node.children[node.children.length-1].x)/2-1;  // -1 是为了防止中间节点的连线无法正确显示
    // }
    // rootNodes.forEach((node) => {
    //   recount(node);
    // });

    this.updateConnections();
  }

  getNodeById(node_id){
    return this.nodes.find(node=>node.id===node_id);
  }

  idFactory(){
    return "node_"+Date.now()+"_"+(this.next_node_id++);
  }
}
